package ddz.numerical.manager;

import com.kaka.numerical.annotation.Numeric;
import ddz.numerical.ConfManager;
import ddz.numerical.pojo.ConfPlaceInfo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 游戏场静态配置数据管理器
 */
@Numeric(src = "conf_place.txt")
public class ConfPlaceInfoManager extends ConfManager<ConfPlaceInfo> {

    private final Map<Integer, ConfPlaceInfo> map = new ConcurrentHashMap<>();
    private final List<ConfPlaceInfo> list = Collections.synchronizedList(new ArrayList<>());
    private final Map<Integer, List<ConfPlaceInfo>> modeMap = new ConcurrentHashMap<>();

    @Override
    protected void cacheObject(ConfPlaceInfo info) {
        if (info.getMaxGold() < 0) {
            info.setMaxGold(Integer.MAX_VALUE);
        }
        map.put(info.getId(), info);
        list.add(info);
        List<ConfPlaceInfo> modeList = modeMap.computeIfAbsent(info.getMode(), k -> new ArrayList<>(4));
        modeList.add(info);
    }

    @Override
    protected void parseBefore() {
        map.clear();
        list.clear();
        modeMap.clear();
    }

    @Override
    protected void parseAfter() {
        this.sortList(list);
        modeMap.forEach((Integer mode, List<ConfPlaceInfo> infoList) -> {
            sortList(infoList);
        });
    }

    private void sortList(List<ConfPlaceInfo> infoList) {
        infoList.sort((ConfPlaceInfo info1, ConfPlaceInfo info2) -> {
            if (info2.getId() > info1.getId()) {
                return -1;
            }
            if (info2.getId() < info1.getId()) {
                return 1;
            }
            return 0;
        });
    }

    public List<ConfPlaceInfo> getListByMode(int mode) {
        return modeMap.get(mode);
    }

    private int buildId(int mode, int place) {
        return mode * 1000 + place;
    }

    public int isExists(int mode, int place) {
        int id = buildId(mode, place);
        if (this.map.containsKey(id)) {
            return id;
        }
        return -1;
    }

    public boolean isExists(int mode) {
        return modeMap.containsKey(mode);
    }

    private ConfPlaceInfo getConfPlaceInfoById(int id) {
        if (id <= 0) id = 1001;
        return this.map.get(id);
    }

    public ConfPlaceInfo getConfPlaceInfo(int mode, int place) {
        if (list.isEmpty()) return null;
        int id = buildId(mode, place);
        return getConfPlaceInfoById(id);
    }

    public List<ConfPlaceInfo> getList() {
        return list;
    }

    public ConfPlaceInfo getConfPlaceInfoByBounds(int mode, int gold) {
        if (list.isEmpty()) return null;
        List<ConfPlaceInfo> infoList = modeMap.get(mode);
        if (infoList == null || infoList.isEmpty()) return null;
        int lastIdx = infoList.size() - 1;
        for (int i = lastIdx; i >= 0; i--) {
            ConfPlaceInfo info = infoList.get(i);
            if (gold >= info.getMinGold() && gold <= info.getMaxGold()) {
                return info;
            }
        }
        return infoList.get(0);
    }
}
